10. Preventing Resource Leaks
Preventing Resource Leaks
In this section, you will:
- Describe common kinds of resource leaks and how they can happen.
- Use
try/catch/finallyto prevent resource leaks. - Apply try-with-resources and the
Closeableinterface to prevent resource leaks. - Prevent closing resources multiple times.
ND079 JPND C2 L02 A12 Preventing Resource Leaks
Why Should We Prevent Resource Leaks?
- Leaving files open wastes memory and other system resources.
- Most operating systems limit the number of files that can be open at one time, so, when you leave a file open after you're done using it, you're potentially depriving programs of the ability to open other files in the future.
- If you are using a buffered writer and forget to close it, the buffered writes might never actually be written to disk.
SOLUTION:
- To avoid wasting resources.
- The operating system limits the number of open files.
- To ensure the file has latest information.
try-catch-finally Example
try-catch-finally can be very useful for preventing resource leaks.
Writer writer;
try {
writer = Files.newBufferedWriter(Path.of("test"));
writer.write("Hello, world!");
} catch (IOException e) {
e.printStackTrace();
} finally {
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
The code in the finally block is guaranteed to execute after the code in the try block, even if the try block returns a value or throws an exception. This code also has a catch block, but that is optional.
try-with-resources Example
try (Writer writer = Files.newBufferedWriter(Path.of("test"))) {
writer.write("Hello, world!");
} catch (IOException e) {
e.printStackTrace();
}
Java 7 introduced the try-with-resources syntax. This new syntax allows you to initialize your resources in parenthesis right before the start of the try block. Resources initialized in this way are guaranteed to be closed after the try block finishes executing.
Although try-with-resources has removed the need for the finally block in a lot of modern Java code, there are still some use cases where the finally block is useful.
By the way, you can initialize multiple resources in the same try statement, like this:
// Copy the contents of "foo" to "bar"
try (InputStream in = Files.newInputStream(Path.of("foo"));
OutputStream out = Files.newOutputStream(Path.of("bar"))) {
out.write(in.readAllBytes());
}
SOLUTION:
- Call the `close()` method inside a `finally` block.
- Using try-with-resources.
Closeable and AutoCloseable
Only Closeable or AutoCloseable objects can be used in the try statement.
Most of the I/O classes we've talked about, including Stream, Reader, Writer, InputStream, and OuptutStream, already implement the Closeable interface, whose close() method can throw an IOException.
AutoCloseable.close() does not throw IOException.
Closeable and AutoCloseable are just regular Java interfaces, which means you can write your own implmentations and then use them in a try-with-resources block!